package com.tust.androidbbsclient.fragment;

import android.annotation.SuppressLint;
import android.content.Context;
import android.os.Bundle;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Base64;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.Toast;

import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.tust.androidbbsclient.R;
import com.tust.androidbbsclient.adapter.ExploreCategoriesRecyclerAdapter;
import com.tust.androidbbsclient.adapter.ExploreExploreListRecyclerAdapter;
import com.tust.androidbbsclient.tool.Tool;
import com.tust.androidbbsclient.trans.ExploreList;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

/**
 * A simple {@link Fragment} subclass.
 * Use the {@link ExploreFragment#newInstance} factory method to
 * create an instance of this fragment.
 */
public class ExploreFragment extends Fragment implements ExploreCategoriesRecyclerAdapter.OnItemClickListener{
    private Toast toast;
    private Context context;
    private List<ExploreList> exploreLists;

    RecyclerView recyclerViewExploreExploreList;
    ExploreExploreListRecyclerAdapter exploreExploreListRecyclerAdapter;

    //用于在线程间传递消息
    @SuppressLint("HandlerLeak")
    private Handler handler = new Handler(Looper.myLooper()) {
        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);//获取子线程传递的消息
            if (msg.what == 1) {//查询(所有)浏览贴文列表请求返回值
                String strMsg = msg.obj.toString();
                //System.out.println("查询评论列表：" + strMsg);

                if (strMsg.equals("serverFalse")) showToast(Tool.addEmoji() + "服务器通信失败！");
                else setRecyclerView(strMsg);//调用RecyclerView设置方法
            } else if (msg.what == 2) {//分页下一页请求返回值
                String strMsg = msg.obj.toString();
                //System.out.println("分页下一页：" + strMsg);

                if (strMsg.equals("serverFalse")) showToast(Tool.addEmoji() + "服务器通信失败！");
                else addRecyclerViewItem(strMsg);//调用RecyclerView设置方法
            }
        }
    };

    // TODO: Rename parameter arguments, choose names that match
    // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
    private static final String ARG_PARAM1 = "param1";
    private static final String ARG_PARAM2 = "param2";

    // TODO: Rename and change types of parameters
    private String mParam1;
    private String mParam2;

    public ExploreFragment() {
        // Required empty public constructor
    }

    /**
     * Use this factory method to create a new instance of
     * this fragment using the provided parameters.
     *
     * @param param1 Parameter 1.
     * @param param2 Parameter 2.
     * @return A new instance of fragment ExploreFragment.
     */
    // TODO: Rename and change types and number of parameters
    public static ExploreFragment newInstance(String param1, String param2) {
        ExploreFragment fragment = new ExploreFragment();
        Bundle args = new Bundle();
        args.putString(ARG_PARAM1, param1);
        args.putString(ARG_PARAM2, param2);
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
            mParam1 = getArguments().getString(ARG_PARAM1);
            mParam2 = getArguments().getString(ARG_PARAM2);
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_explore, container, false);
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        context = getContext();

        RecyclerView recyclerViewExploreCategories = view.findViewById(R.id.rv_exploreCategories);
        recyclerViewExploreExploreList = view.findViewById(R.id.rv_exploreArtList);
        EditText editTextExploreSearchArtBar = view.findViewById(R.id.et_exploreSearchArtBar);
        ImageButton imageButtonExploreSearchArtIcon = view.findViewById(R.id.ibtn_exploreSearchArtIcon);
        FloatingActionButton floatingActionButtonExploreArtList = view.findViewById(R.id.fab_exploreArtList);

        //设置默认选中类别
        Tool.selectedCategory = context.getResources().getStringArray(R.array.categories)[0];

        //设置横向类别RecyclerView
        ExploreCategoriesRecyclerAdapter exploreCategoriesRecyclerAdapter = new ExploreCategoriesRecyclerAdapter(context, context.getResources().getStringArray(R.array.categories));//构造Recycler适配器
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false);//创建线性布局管理器,子项布局水平方向，从左侧开始排列
        recyclerViewExploreCategories.setLayoutManager(linearLayoutManager);//为RecyclerView设置布局管理器
        exploreCategoriesRecyclerAdapter.setOnItemClickListener(this);//item监听点击事件，置入当前类实例（包含onItemClick实现方法）
        recyclerViewExploreCategories.setAdapter(exploreCategoriesRecyclerAdapter);//为RecyclerView设置适配器

        showToast(Tool.addEmoji() + "正在请求数据，请稍候！");

        //发送查询所有浏览贴文列表请求子线程
        new Thread() {
            @Override
            public void run() {
                OutputStream outputStream = null;
                BufferedReader bufferedReader = null;
                String data = "";
                try {
                    Message handlerMsg = Message.obtain();//构造Message对象，用于向主线程传递消息
                    handlerMsg.what = 1;//增加handlerMsg标识符

                    URL url = new URL(Tool.InetAddress + "/searchAllExploreList.do");//请求地址
                    HttpURLConnection connection = (HttpURLConnection) url.openConnection();

                    //连接类相关设置
                    connection.setRequestMethod("POST");
                    connection.setConnectTimeout(10000);//连接服务器超时
                    connection.setReadTimeout(10000);//从服务器读取数据超时
                    connection.setDoInput(true);//允许写入，从服务端读取结果流
                    connection.setDoOutput(true);//允许写出，开启Post请求体
                    connection.setUseCaches(false);//不使用Cache
                    connection.setInstanceFollowRedirects(true);//自动处理重定向，成功获得200状态码
                    connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");//设置http请求头格式
                    connection.setRequestProperty("Connection", "Keep-Alive");//大数据保持连接

                    connection.connect();//连接网络
                    String params = "ArtCategory=" + Tool.selectedCategory;//请求体内容
                    outputStream = connection.getOutputStream();//请求输出流
                    outputStream.write(params.getBytes());

                    int code = connection.getResponseCode();//获得响应状态码
                    if (code == 200) {//返回状态码200，连接成功
                        bufferedReader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
                        data = bufferedReader.readLine();

                        handlerMsg.obj = data;//写入线程传递消息
                    } else handlerMsg.obj = "serverFalse";//服务器通信失败
                    connection.disconnect();//关闭连接

                    handler.sendMessage(handlerMsg);//发送线程消息
                } catch (IOException e) {
                    Message handlerMsg = Message.obtain();//构造Message对象，用于向主线程传递消息
                    handlerMsg.what = 1;//增加handlerMsg标识符
                    handlerMsg.obj = "serverFalse";
                    handler.sendMessage(handlerMsg);

                    //throw new RuntimeException(e);
                } finally {
                    try {
                        if (bufferedReader != null) bufferedReader.close();
                        if (outputStream != null) {
                            outputStream.flush();
                            outputStream.close();
                        }
                    } catch (IOException e) {
                        System.out.println("子线程：finally失败");
                        //throw new RuntimeException(e);
                    }
                }
            }
        }.start();

        //搜索图片按钮监听事件
        imageButtonExploreSearchArtIcon.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                String searchContent = editTextExploreSearchArtBar.getText().toString();

                if (searchContent.equals("")) {
                    showToast(Tool.addEmoji() + "刷新列表内容！");

                    //发送查询所有贴文列表请求子线程
                    new Thread() {
                        @Override
                        public void run() {
                            OutputStream outputStream = null;
                            BufferedReader bufferedReader = null;
                            String data = "";
                            try {
                                Message handlerMsg = Message.obtain();//构造Message对象，用于向主线程传递消息
                                handlerMsg.what = 1;//增加handlerMsg标识符

                                URL url = new URL(Tool.InetAddress + "/searchAllExploreList.do");//请求地址
                                HttpURLConnection connection = (HttpURLConnection) url.openConnection();

                                //连接类相关设置
                                connection.setRequestMethod("POST");
                                connection.setConnectTimeout(10000);//连接服务器超时
                                connection.setReadTimeout(10000);//从服务器读取数据超时
                                connection.setDoInput(true);//允许写入，从服务端读取结果流
                                connection.setDoOutput(true);//允许写出，开启Post请求体
                                connection.setUseCaches(false);//不使用Cache
                                connection.setInstanceFollowRedirects(true);//自动处理重定向，成功获得200状态码
                                connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");//设置http请求头格式
                                connection.setRequestProperty("Connection", "Keep-Alive");//大数据保持连接

                                connection.connect();//连接网络
                                String params = "ArtCategory=" + Tool.selectedCategory;//请求体内容
                                outputStream = connection.getOutputStream();//请求输出流
                                outputStream.write(params.getBytes());

                                int code = connection.getResponseCode();//获得响应状态码
                                if (code == 200) {//返回状态码200，连接成功
                                    bufferedReader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
                                    data = bufferedReader.readLine();

                                    handlerMsg.obj = data;//写入线程传递消息
                                } else handlerMsg.obj = "serverFalse";//服务器通信失败
                                connection.disconnect();//关闭连接

                                handler.sendMessage(handlerMsg);//发送线程消息
                            } catch (IOException e) {
                                Message handlerMsg = Message.obtain();//构造Message对象，用于向主线程传递消息
                                handlerMsg.what = 1;//增加handlerMsg标识符
                                handlerMsg.obj = "serverFalse";
                                handler.sendMessage(handlerMsg);

                                //throw new RuntimeException(e);
                            } finally {
                                try {
                                    if (bufferedReader != null) bufferedReader.close();
                                    if (outputStream != null) {
                                        outputStream.flush();
                                        outputStream.close();
                                    }
                                } catch (IOException e) {
                                    System.out.println("子线程：finally失败");
                                    //throw new RuntimeException(e);
                                }
                            }
                        }
                    }.start();
                } else {
                    showToast(Tool.addEmoji() + "查询“" + searchContent + "”相关的贴文！");

                    //发送查询贴文列表请求子线程
                    new Thread() {
                        @Override
                        public void run() {
                            OutputStream outputStream = null;
                            BufferedReader bufferedReader = null;
                            String data = "";
                            try {
                                Message handlerMsg = Message.obtain();//构造Message对象，用于向主线程传递消息
                                handlerMsg.what = 1;//增加handlerMsg标识符

                                URL url = new URL(Tool.InetAddress + "/searchExploreList.do");//请求地址
                                HttpURLConnection connection = (HttpURLConnection) url.openConnection();

                                //连接类相关设置
                                connection.setRequestMethod("POST");
                                connection.setConnectTimeout(10000);//连接服务器超时
                                connection.setReadTimeout(10000);//从服务器读取数据超时
                                connection.setDoInput(true);//允许写入，从服务端读取结果流
                                connection.setDoOutput(true);//允许写出，开启Post请求体
                                connection.setUseCaches(false);//不使用Cache
                                connection.setInstanceFollowRedirects(true);//自动处理重定向，成功获得200状态码
                                connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");//设置http请求头格式
                                connection.setRequestProperty("Connection", "Keep-Alive");//大数据保持连接

                                connection.connect();//连接网络
                                String params = "ArtCategory=" + Tool.selectedCategory + "&searchContent=" + searchContent;//请求体内容
                                outputStream = connection.getOutputStream();//请求输出流
                                outputStream.write(params.getBytes());

                                int code = connection.getResponseCode();//获得响应状态码
                                if (code == 200) {//返回状态码200，连接成功
                                    bufferedReader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
                                    data = bufferedReader.readLine();

                                    handlerMsg.obj = data;//写入线程传递消息
                                } else handlerMsg.obj = "serverFalse";//服务器通信失败
                                connection.disconnect();//关闭连接

                                handler.sendMessage(handlerMsg);//发送线程消息
                            } catch (IOException e) {
                                Message handlerMsg = Message.obtain();//构造Message对象，用于向主线程传递消息
                                handlerMsg.what = 1;//增加handlerMsg标识符
                                handlerMsg.obj = "serverFalse";
                                handler.sendMessage(handlerMsg);

                                //throw new RuntimeException(e);
                            } finally {
                                try {
                                    if (bufferedReader != null) bufferedReader.close();
                                    if (outputStream != null) {
                                        outputStream.flush();
                                        outputStream.close();
                                    }
                                } catch (IOException e) {
                                    System.out.println("子线程：finally失败");
                                    //throw new RuntimeException(e);
                                }
                            }
                        }
                    }.start();
                }
            }
        });

        //RecyclerView滚动监听事件
        recyclerViewExploreExploreList.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);

                //滚动到底部时
                if (!recyclerView.canScrollVertically(1)) {
                    //showToast(Tool.addEmoji() + "已到达底部！");

                    //发送分页下一页请求子线程
                    new Thread() {
                        @Override
                        public void run() {
                            BufferedReader bufferedReader = null;
                            String data = "";
                            try {
                                Message handlerMsg = Message.obtain();//构造Message对象，用于向主线程传递消息
                                handlerMsg.what = 2;//增加handlerMsg标识符

                                URL url = new URL(Tool.InetAddress + "/nextExploreListPage.do");//请求地址
                                HttpURLConnection connection = (HttpURLConnection) url.openConnection();

                                //连接类相关设置
                                connection.setRequestMethod("POST");
                                connection.setConnectTimeout(10000);//连接服务器超时
                                connection.setReadTimeout(10000);//从服务器读取数据超时
                                connection.setDoInput(true);//允许写入，从服务端读取结果流
                                connection.setDoOutput(true);//允许写出，开启Post请求体
                                connection.setUseCaches(false);//不使用Cache
                                connection.setInstanceFollowRedirects(true);//自动处理重定向，成功获得200状态码
                                connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");//设置http请求头格式
                                connection.setRequestProperty("Connection", "Keep-Alive");//大数据保持连接

                                connection.connect();//连接网络

                                int code = connection.getResponseCode();//获得响应状态码
                                if (code == 200) {//返回状态码200，连接成功
                                    bufferedReader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
                                    data = bufferedReader.readLine();

                                    handlerMsg.obj = data;//写入线程传递消息
                                } else handlerMsg.obj = "serverFalse";//服务器通信失败
                                connection.disconnect();//关闭连接

                                handler.sendMessage(handlerMsg);//发送线程消息
                            } catch (IOException e) {
                                Message handlerMsg = Message.obtain();//构造Message对象，用于向主线程传递消息
                                handlerMsg.what = 2;//增加handlerMsg标识符
                                handlerMsg.obj = "serverFalse";
                                handler.sendMessage(handlerMsg);

                                //throw new RuntimeException(e);
                            } finally {
                                try {
                                    if (bufferedReader != null) bufferedReader.close();
                                } catch (IOException e) {
                                    System.out.println("子线程：finally失败");
                                    //throw new RuntimeException(e);
                                }
                            }
                        }
                    }.start();
                }
            }
        });

        //悬浮按钮监听事件
        floatingActionButtonExploreArtList.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                recyclerViewExploreExploreList.smoothScrollToPosition(0);//平滑滚动到顶部
            }
        });
    }

    //获取当前选中类别和后续处理
    @Override
    public void onItemClick(String category) {
        showToast(Tool.addEmoji() + "正在请求数据，请稍候！");

        //发送查询所有浏览贴文列表请求子线程
        new Thread() {
            @Override
            public void run() {
                OutputStream outputStream = null;
                BufferedReader bufferedReader = null;
                String data = "";
                try {
                    Message handlerMsg = Message.obtain();//构造Message对象，用于向主线程传递消息
                    handlerMsg.what = 1;//增加handlerMsg标识符

                    URL url = new URL(Tool.InetAddress + "/searchAllExploreList.do");//请求地址
                    HttpURLConnection connection = (HttpURLConnection) url.openConnection();

                    //连接类相关设置
                    connection.setRequestMethod("POST");
                    connection.setConnectTimeout(10000);//连接服务器超时
                    connection.setReadTimeout(10000);//从服务器读取数据超时
                    connection.setDoInput(true);//允许写入，从服务端读取结果流
                    connection.setDoOutput(true);//允许写出，开启Post请求体
                    connection.setUseCaches(false);//不使用Cache
                    connection.setInstanceFollowRedirects(true);//自动处理重定向，成功获得200状态码
                    connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");//设置http请求头格式
                    connection.setRequestProperty("Connection", "Keep-Alive");//大数据保持连接

                    connection.connect();//连接网络
                    String params = "ArtCategory=" + category;//请求体内容
                    outputStream = connection.getOutputStream();//请求输出流
                    outputStream.write(params.getBytes());

                    int code = connection.getResponseCode();//获得响应状态码
                    if (code == 200) {//返回状态码200，连接成功
                        bufferedReader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
                        data = bufferedReader.readLine();

                        handlerMsg.obj = data;//写入线程传递消息
                    } else handlerMsg.obj = "serverFalse";//服务器通信失败
                    connection.disconnect();//关闭连接

                    handler.sendMessage(handlerMsg);//发送线程消息
                } catch (IOException e) {
                    Message handlerMsg = Message.obtain();//构造Message对象，用于向主线程传递消息
                    handlerMsg.what = 1;//增加handlerMsg标识符
                    handlerMsg.obj = "serverFalse";
                    handler.sendMessage(handlerMsg);

                    //throw new RuntimeException(e);
                } finally {
                    try {
                        if (bufferedReader != null) bufferedReader.close();
                        if (outputStream != null) {
                            outputStream.flush();
                            outputStream.close();
                        }
                    } catch (IOException e) {
                        System.out.println("子线程：finally失败");
                        //throw new RuntimeException(e);
                    }
                }
            }
        }.start();
    }

    //设置RecyclerView
    private void setRecyclerView(String exploreListData) {
        exploreLists = new ArrayList<>();
        //解析JSON字符串
        try {
            JSONArray jsonArray = new JSONArray(exploreListData);
            for (int i = 0; i < jsonArray.length(); i++) {
                JSONObject jsonObject = jsonArray.getJSONObject(i);
                try {
                    exploreLists.add(
                            new ExploreList(
                                    Integer.parseInt(jsonObject.getString("artID")),
                                    jsonObject.getString("uname"),
                                    jsonObject.getString("artSubTime"),
                                    jsonObject.getString("artCategory"),
                                    jsonObject.getString("artTitle"),
                                    jsonObject.getString("artContent"),
                                    Base64.decode(jsonObject.getString("artPic1").replaceAll("dataimage/jpegbase64", ""), Base64.DEFAULT),
                                    Integer.parseInt(jsonObject.getString("artFavorNum")),
                                    Integer.parseInt(jsonObject.getString("artCollNum")),
                                    Integer.parseInt(jsonObject.getString("artComNum"))
                            )
                    );
                } catch (IllegalArgumentException e) {
                    //showToast(Tool.addEmoji() + "显示图片失败！");
                    System.out.println("ArtID=" + jsonObject.getString("artID") + " 抛出异常：Base64编码中有非法字符");

                    exploreLists.add(
                            new ExploreList(
                                    Integer.parseInt(jsonObject.getString("artID")),
                                    jsonObject.getString("uname"),
                                    jsonObject.getString("artSubTime"),
                                    jsonObject.getString("artCategory"),
                                    jsonObject.getString("artTitle"),
                                    jsonObject.getString("artContent"),
                                    null,
                                    Integer.parseInt(jsonObject.getString("artFavorNum")),
                                    Integer.parseInt(jsonObject.getString("artCollNum")),
                                    Integer.parseInt(jsonObject.getString("artComNum"))
                            )
                    );
                }
            }
        } catch (JSONException e) {
            throw new RuntimeException(e);
        }

        if (exploreLists.size() > 0) ;//showToast(Tool.addEmoji() + "已请求到数据，正在加载！");
        else showToast(Tool.addEmoji() + "暂时没有帖子，请稍后再来！");

        exploreExploreListRecyclerAdapter = new ExploreExploreListRecyclerAdapter(context, this, exploreLists);//构造Recycler适配器
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(context);//创建线性布局管理器,默认子项布局垂直方向
        linearLayoutManager.setReverseLayout(false);//子项布局从顶部开始排列
        recyclerViewExploreExploreList.setLayoutManager(linearLayoutManager);//为RecyclerView设置布局管理器
        recyclerViewExploreExploreList.setAdapter(exploreExploreListRecyclerAdapter);//为RecyclerView设置适配器
    }

    //动态增加RecyclerView子项
    private void addRecyclerViewItem(String addExploreListData) {
        List<ExploreList> addExploreLists = new ArrayList<>();//增加的浏览贴文列表
        //解析JSON字符串
        try {
            JSONArray jsonArray = new JSONArray(addExploreListData);
            for (int i = 0; i < jsonArray.length(); i++) {
                JSONObject jsonObject = jsonArray.getJSONObject(i);
                addExploreLists.add(
                        new ExploreList(
                                Integer.parseInt(jsonObject.getString("artID")),
                                jsonObject.getString("uname"),
                                jsonObject.getString("artSubTime"),
                                jsonObject.getString("artCategory"),
                                jsonObject.getString("artTitle"),
                                jsonObject.getString("artContent"),
                                Base64.decode(jsonObject.getString("artPic1").replaceAll("dataimage/jpegbase64", ""), Base64.DEFAULT),
                                Integer.parseInt(jsonObject.getString("artFavorNum")),
                                Integer.parseInt(jsonObject.getString("artCollNum")),
                                Integer.parseInt(jsonObject.getString("artComNum"))
                        )
                );
            }
        } catch (JSONException e) {
            throw new RuntimeException(e);
        }

        exploreLists.addAll(addExploreLists);
        if (addExploreLists.size() > 0) showToast(Tool.addEmoji() + "正在加载更多！");
        else showToast(Tool.addEmoji() + "已全部加载完成！");

        //动态增加RecyclerView子项
        exploreExploreListRecyclerAdapter.notifyItemRangeInserted(exploreLists.size() - addExploreLists.size(), addExploreLists.size());
    }

    //Toast消息提示框显示方法
    private void showToast(String s) {
        if (toast == null){
            toast = Toast.makeText(context, s, Toast.LENGTH_SHORT);
        }else {
            toast.cancel();
            toast = Toast.makeText(context, s, Toast.LENGTH_SHORT);
        }
        toast.show();
    }
}
